<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>04_生命周期（老版）</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
    <div id="app"></div>
    <script type="text/babel">
        /*
        React组件的生命周期分为三个阶段：
        1、初始化阶段
            1、constructor()
            2、componentWillMount()
            3、render()
            4、componentDidMount()
        2、更新阶段
            1、shouldComponentUpdate()
            2、componentWillUpdate()
            3、render()
            4、componentDidUpdate()
        3、卸载阶段
            1、componentWillUnmount()

        以上生命周期比较重要的是：
        1、constructor()
        2、componentDidMount()
        3、componentWillUnmount()

        需要理解的生命周期：
        1、shouldComponentUpdate()
        2、render()

        */
        let app = document.getElementById("app")
        let {Fragment,Component,PureComponent} = React

        class App extends Component{
            render(){
                return <fieldset>
                    <legend><h2>App组件</h2></legend>
                    <Child1></Child1>
                </fieldset>
            }
        }
        class Child1 extends PureComponent{
            constructor(props) {
                super(props);
                this.state={
                    c1Msg:"今天是幸运日"
                }
                // 组件的构造函数，是最先触发的生命周期，在整个组件运行期间只走一次，
                // 我们经常在该函数里初始化state，或者修改函数的this指向或者做一些初始化操作
                console.log("Child1的constructor触发了")
            }
            componentWillMount(){
                // 组件实例创建完毕，将要被挂载之前触发
                console.log("Child1的componentWillMount触发了")
            }
            render(){
                // 该方法用于渲染UI界面
                /*
                该方法的注意事项：
                1、永远不要手动调用该方法
                2、绝大部分情况下返回的是JSX结构
                3、该方法除了在组件首次实例化时调用之外，将来调用setState,或者组件的父组件更新，该方法也会调用，重新渲染页面
                4、该方法也可以被阻止触发，可以利用shouldComponentUpdate()阻止组件重新渲染
                */
                console.log("Child1的render触发了")
                return <fieldset>
                    <legend><h2>Child1组件</h2></legend>
                    <p>msg的值是：{this.state.c1Msg}</p>
                    <button onClick={()=>this.changeMsg()} >改变msg</button>
                </fieldset>
            }
            componentDidMount(){
                // 该方法在组件挂载完毕之后触发，我们一般会在此发起网络请求
                console.log("Child1的componentDidMount触发了")
            }

            /*shouldComponentUpdate(newPros,newState){
                // 该方法会在执行渲染之前被调用，默认有返回值，值为true，如果返回值为false，就不会继续执行render方法，相当于禁止了组件的数据更新
                console.log("Child1的shouldComponentUpdate触发了",newState.c1Msg,this.state.c1Msg)
                // 我们将来可以在该方法里对频繁修改的变量做判断，提高react的渲染效率
                // 但是该方法在比较的时候，注意，如果是复杂数据类型，不建议比较
                // 如果懒得写shouldComponentUpdate，可以考虑将组件的继承由Component修改成PureComponent
                if(this.state.c1Msg != newState.c1Msg){
                    return true;
                }else{
                    return false;
                }

            }*/
            componentWillUpdate(){
                // 该方法会在组件更新数据之前被调用
                console.log("Child1的componentWillUpdate触发了")
            }
            componentDidUpdate(){
                // 该方法会在组件数据更新完毕之后触发
                console.log("Child1的componentDidUpdate触发了")
            }

            componentWillUnmount(){
                // 该方法在组件将要被卸载之前触发，我们可以在此时做一些收尾的事情：比如关闭定时器，取消监听，暂停音频视频数据等
                console.log("Child1的componentWillUnmount触发了")
            }

            changeMsg(){
                this.setState({
                    c1Msg: "明天周四"
                })
                /*this.setState((state)=>{
                    return {
                        c1Msg: state.c1Msg+"修改"
                    }
                })*/
            }
        }

        ReactDOM.render(<App></App>,app);
    </script>
</body>
</html>